package com.lottery.material.controller.portal.user;

import com.lottery.material.controller.base.BaseController;
import com.lottery.material.enumeration.ResultEnum;
import com.lottery.material.jedis.JedisClient;
import com.lottery.material.pojo.article.ArticleInfo;
import com.lottery.material.pojo.circle.CircleMemberInfo;
import com.lottery.material.pojo.circle.CircleRuleConfig;
import com.lottery.material.pojo.page.PageData;
import com.lottery.material.pojo.portaluser.PortalUserInfo;
import com.lottery.material.pojo.promotion.PromotionRuleConfig;
import com.lottery.material.pojo.transaction.TransactionRecord;
import com.lottery.material.resolver.CustomException;
import com.lottery.material.service.portal.article.ArticleCompetitionInfoService;
import com.lottery.material.service.portal.article.ArticleInfoService;
import com.lottery.material.service.portal.circle.CircleMemberInfoService;
import com.lottery.material.service.portal.circle.CircleRuleConfigService;
import com.lottery.material.service.portal.config.SystemParameterConfigService;
import com.lottery.material.service.portal.promotion.PromotionRealtimeRecordService;
import com.lottery.material.service.portal.promotion.PromotionRuleConfigService;
import com.lottery.material.service.portal.transaction.TransactionRecordService;
import com.lottery.material.service.portal.user.PortalUserInfoService;
import com.lottery.material.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Description:    金币支付Controller
 * Author:         sunny
 * CreateDate:     2019-04-16 14:53
 */
@RequestMapping("/portal/user")
@Slf4j
@Controller
public class PortalUserGoldPayController extends BaseController {

    @Autowired
    @Qualifier("jedisClientCluster")
    private JedisClient jedisClient;

    @Autowired
    private PortalUserInfoService portalUserInfoService;
    @Autowired
    private CircleMemberInfoService circleMemberInfoService;
    @Autowired
    private CircleRuleConfigService circleRuleConfigService;
    @Autowired
    private ArticleInfoService articleInfoService;
    @Autowired
    private TransactionRecordService transactionRecordService;
    @Autowired
    private ArticleCompetitionInfoService articleCompetitionInfoService;
    @Autowired
    private PromotionRealtimeRecordService promotionRealtimeRecordService;
    @Autowired
    private SystemParameterConfigService systemParameterConfigService;
    @Autowired
    private PromotionRuleConfigService promotionRuleConfigService;

    /**
     * description: 金币支付
     * author sunny
     * createDate 2019-04-16 下午 2:55
     * @param request
     * @return
     */
    @RequestMapping(value = "/goldPay", method = RequestMethod.POST)
    @ResponseBody
    public ResponseResult goldPay(HttpServletRequest request) {
        Map<String, String> reqParamMap = new HashMap<>();
        //解析参数
        if (ParameterUtil.analyticParameter(request, reqParamMap)) {
            throw new CustomException(ResultEnum.PARSE_EXCEPTION);
        }

        //非空判断
        ResponseResult respDate = parameterValidate(reqParamMap);
        if (null != respDate) {
            return respDate;
        }

        try {
            //获取用户当前可用金币
            PortalUserInfo portalUserInfo = portalUserInfoService.findByUserId(reqParamMap.get("userId"));
            BigDecimal GoldTotal = new BigDecimal(MathUtil.addHalfUp(String.valueOf(portalUserInfo.getGoldBuy()), String.valueOf(portalUserInfo.getGoldProfit()), 0));

            //验证金币是否足够支付
            if (GoldTotal.compareTo(new BigDecimal(reqParamMap.get("payAmount"))) == -1) {
                return ResponseResult.buildResult(ResultEnum.NOT_ENOUGH_GOLD_FAIL);
            }

            if ("TLX00003".equals(reqParamMap.get("transactionTypeCode"))) { //TLX00003:专家认证
                return expertAuth(portalUserInfo, reqParamMap);
            } else if ("TLX00004".equals(reqParamMap.get("transactionTypeCode"))) { //TLX00004:圈员认证
                return circleAuth(portalUserInfo, reqParamMap);
            } else if ("TLX00005".equals(reqParamMap.get("transactionTypeCode"))) { //TLX00005:查看收费文章
                return viewArticle(portalUserInfo, reqParamMap);
            } else if ("TLX00006".equals(reqParamMap.get("transactionTypeCode"))) { //TLX00006:打赏文章
                return rewardArticle(portalUserInfo, reqParamMap);
            } else if ("TLX00007".equals(reqParamMap.get("transactionTypeCode"))) { //TLX00007:付费推广
                return promotionPay(portalUserInfo, reqParamMap);
            }
            return ResponseResult.buildResult(ResultEnum.PAYMENT_FAIL);
        } catch (Exception e) {
            log.error("【金币支付出现异常】:{}", ExceptionUtil.logExceptionStack(e));
            throw new CustomException(ResultEnum.PAYMENT_FAIL);
        }
    }

    /**
     * description: 参数验证
     * author sunny
     * createDate 2019-04-17 下午 1:31
     *
     * @param reqParamMap
     * @return
     */
    private ResponseResult parameterValidate(Map<String, String> reqParamMap) {
        //非空判断及用户登录是否过期验证
        ParameterUtil.checkLogin(reqParamMap, jedisClient, portalUserInfoService);

        ResponseResult respDate = validateEmpty(reqParamMap);
        if (null != respDate) {
            return respDate;
        }

        String transactionTypeCode = reqParamMap.get("transactionTypeCode");
        if (StringUtils.isBlank(transactionTypeCode)) {
            return ResponseResult.buildFormatResult(ResultEnum.PARAMETER_NOT_NULL, "transactionTypeCode");
        } else if ("TLX00004".equals(transactionTypeCode)) {
            String circleId = reqParamMap.get("circleId");
            if (StringUtils.isBlank(circleId)) {
                return ResponseResult.buildFormatResult(ResultEnum.PARAMETER_NOT_NULL, "circleId");
            }
        } else if ("TLX00005".equals(transactionTypeCode) || "TLX00006".equals(transactionTypeCode)
                || "TLX00007".equals(transactionTypeCode) || "TLX00008".equals(transactionTypeCode)) {
            String articleId = reqParamMap.get("articleId");
            if (StringUtils.isBlank(articleId)) {
                return ResponseResult.buildFormatResult(ResultEnum.PARAMETER_NOT_NULL, "articleId");
            }
            if ("TLX00005".equals(transactionTypeCode) || "TLX00006".equals(transactionTypeCode)) {
                String isSkipValidation = reqParamMap.get("isSkipValidation");
                if (StringUtils.isBlank(isSkipValidation)) {
                    return ResponseResult.buildFormatResult(ResultEnum.PARAMETER_NOT_NULL, "isSkipValidation");
                } else {
                    if (!"1".equals(isSkipValidation) && !"2".equals(isSkipValidation)) {
                        return ResponseResult.buildFormatResult(ResultEnum.PARAMETER_ERROR, "isSkipValidation");
                    }
                }
                if("TLX00006".equals(transactionTypeCode)){
                    String rewardReasonCode = reqParamMap.get("rewardReasonCode");
                    if (StringUtils.isBlank(rewardReasonCode)) {
                        return ResponseResult.buildFormatResult(ResultEnum.PARAMETER_NOT_NULL, "rewardReasonCode");
                    }
                }
            }
        }
        String payAmount = reqParamMap.get("payAmount");
        if (StringUtils.isBlank(payAmount)) {
            return ResponseResult.buildFormatResult(ResultEnum.PARAMETER_NOT_NULL, "payAmount");
        }

        //签名验证
        ResponseResult responseResult = ParameterUtil.checkSign(reqParamMap);
        if (null != responseResult) {
            return responseResult;
        }
        return null;
    }

    /**
     * description: 专家认证
     * author sunny
     * createDate 2019-04-17 下午 1:36
     *
     * @param portalUserInfo
     * @param reqParamMap
     * @return
     */
    private ResponseResult expertAuth(PortalUserInfo portalUserInfo, Map<String, String> reqParamMap) {
        if(portalUserInfo.getUserType() != 1){ //非普通用户，不让再次认证
            return ResponseResult.buildResult(ResultEnum.ALREADY_AUTH_USER_FAIL);
        }
        //判断是否进行身份认证
        if (StringUtils.isBlank(portalUserInfo.getIdNumber())) {
            return ResponseResult.buildResult(ResultEnum.NOT_IDENTITY_AUTH_FAIL);
        }
        //判断是否绑定银行卡
        if (StringUtils.isBlank(portalUserInfo.getBankCardNumber())) {
            return ResponseResult.buildResult(ResultEnum.NOT_BANK_CARD_NUMBER_FAIL);
        }
        return portalUserInfoService.insertUserGoldPayRecord(portalUserInfo, reqParamMap);
    }

    /**
     * description: 圈员认证
     * author sunny
     * createDate 2019-04-17 下午 3:13
     *
     * @param portalUserInfo
     * @param reqParamMap
     * @return
     */
    private ResponseResult circleAuth(PortalUserInfo portalUserInfo, Map<String, String> reqParamMap) {
        String userId = reqParamMap.get("userId");
        String circleId = reqParamMap.get("circleId");
        //查询当前用户是否关注该圈子
        PageData pd = new PageData();
        pd.put("userId", userId);
        pd.put("circleId", circleId);
        CircleMemberInfo circleMemberInfo = circleMemberInfoService.findByUserIdAndCircleId(pd);
        if (Objects.isNull(circleMemberInfo)) {
            return ResponseResult.buildResult(ResultEnum.NOT_FOLLOW_CIRCLE_FAIL);
        }
        if (1 != circleMemberInfo.getRank()) { //非预备圈员
            return ResponseResult.buildResult(ResultEnum.ALREADY_CIRCLE_MEMBER_FAIL);
        }

        //根据用户userId及圈子id查询累计发帖量
        Integer postCount = articleInfoService.findCountByUserIdAndCircleId(userId, circleId);
        CircleRuleConfig circleRuleConfig = circleRuleConfigService.findCircleRule();
        if (postCount.compareTo(circleRuleConfig.getPostTotal()) == -1) {
            Integer needCount = circleRuleConfig.getPostTotal() - postCount; //计算还差多少篇
            return ResponseResult.buildFormatResult(ResultEnum.NOT_QUALIFIED_POST_TOTAL_FAIL, postCount, needCount);
        }
        return portalUserInfoService.insertUserGoldPayRecord(portalUserInfo, reqParamMap);
    }

    /**
     * description: 查看收费文章
     * author sunny
     * createDate 2019-04-17 下午 7:54
     *
     * @param portalUserInfo
     * @param reqParamMap
     * @return
     */
    private ResponseResult viewArticle(PortalUserInfo portalUserInfo, Map<String, String> reqParamMap) {
        if ("1".equals(reqParamMap.get("isSkipValidation"))) { //不跳过验证
            String payAmount = reqParamMap.get("payAmount");
            ArticleInfo articleInfo = articleInfoService.findByArticleId(reqParamMap.get("articleId"));
            if (Objects.isNull(articleInfo)) {
                return ResponseResult.buildResult(ResultEnum.ARTICLE_NOT_EXIST_FAIL);
            }

            //文章赛事结束处理
            competitionHandle(articleInfo);

            //验证存在赛事的文章且赛事已经结束
            if (2 == articleInfo.getIsExistCompetition() && 2 == articleInfo.getIsCompetitionEnd()) {
                //判断收费文章是否公开
                if (1 == articleInfo.getIsEndPublic()){ //不公开
                    return ResponseResult.buildFormatResult(ResultEnum.VIEW_NOT_PUBLIC_ARTICLE_CONFIRM_SUCCESS, payAmount);
                }else{
                    if(CalendarUtil.compare(CalendarUtil.getSystemCurrentDate(), articleInfo.getPublicTime()) == 1){
                        return ResponseResult.buildResult(ResultEnum.VIEW_PUBLIC_ARTICLE_CONFIRM_SUCCESS);
                    }
                }
            }
            return ResponseResult.buildFormatResult(ResultEnum.VIEW_ARTICLE_CONFIRM_SUCCESS, payAmount);
        } else {
            return portalUserInfoService.insertUserGoldPayRecord(portalUserInfo, reqParamMap);
        }
    }

    /**
     * description: 打赏文章
     * author sunny
     * createDate 2019-04-18 上午 10:14
     *
     * @param portalUserInfo
     * @param reqParamMap
     * @return
     */
    private ResponseResult rewardArticle(PortalUserInfo portalUserInfo, Map<String, String> reqParamMap) {
        if ("1".equals(reqParamMap.get("isSkipValidation"))) { //不跳过验证
            TransactionRecord transactionRecord = new TransactionRecord();
            transactionRecord.setUserId(reqParamMap.get("userId"));
            transactionRecord.setArticleId(reqParamMap.get("articleId"));
            transactionRecord.setTransactionTypeCode(reqParamMap.get("transactionTypeCode"));
            Integer recordCount = transactionRecordService.findCountByObject(transactionRecord);
            if (recordCount >= 1) {
                return ResponseResult.buildResult(ResultEnum.ALREADY_REWARD_ARTICLE_SUCCESS);
            } else {
                return portalUserInfoService.insertUserGoldPayRecord(portalUserInfo, reqParamMap);
            }
        } else {
            return portalUserInfoService.insertUserGoldPayRecord(portalUserInfo, reqParamMap);
        }
    }

    /**
     * description: 付费推广
     * author sunny
     * createDate 2019-04-18 下午 3:38
     * @param portalUserInfo
     * @param reqParamMap
     * @return
     */
    private ResponseResult promotionPay(PortalUserInfo portalUserInfo, Map<String, String> reqParamMap) {
        //获取圈子内文章推广规则配置信息
        PromotionRuleConfig promotionRuleConfig = promotionRuleConfigService.findByPromotionType(1);
        //计算出当前正在推广的文章总数
        Integer currentPromotionCount = promotionRealtimeRecordService.findCurrentPromotionCount();

        if(promotionRuleConfig.getPromotionLimit().compareTo(currentPromotionCount) != 1){ //推广名额已经超出系统设置最大量
            return ResponseResult.buildResult(ResultEnum.PROMOTION_PAY_FAIL);
        }
        return portalUserInfoService.insertUserGoldPayRecord(portalUserInfo, reqParamMap);
    }

    /**
     * description: 文章赛事结束处理
     * author sunny
     * createDate 2019-04-19 下午 2:44
     */
    private void competitionHandle(ArticleInfo articleInfo){
        if(2 == articleInfo.getIsExistCompetition() && 1 == articleInfo.getIsCompetitionEnd()){
            boolean flag = true;
            //查询文章中存在所有收费的比赛
            List<Map<String, Object>> competitionInfos = articleCompetitionInfoService.findByArticleIdAndType(articleInfo.getArticleId(), 2);
            if(null != competitionInfos && competitionInfos.size() > 0) {
                for (Map<String, Object> competitionMap : competitionInfos) {
                    String score = (String) competitionMap.get("score");
                    Integer state = (Integer) competitionMap.get("state");
                    if (StringUtils.isBlank(score) && state <= 2) {
                        flag = false;
                        break;
                    }
                }
            }else{
                flag = false;
            }

            if(flag){
                //修改文章中所含赛事为结束状态
                articleInfoService.updateIsCompetitionEndForTrue(articleInfo.getArticleId());
                articleInfo.setIsCompetitionEnd(2);
            }
        }
    }
}
